package gtug.duesseldorf.server;

import gtug.duesseldorf.client.GreetingService;
import gtug.duesseldorf.client.model.ClientLoginData;
import gtug.duesseldorf.server.util.AssertUtil;

import java.text.MessageFormat;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService {

	private static final Log LOG = LogFactory.getLog(GreetingServiceImpl.class);

	/**
	 * get client or throw an exception if there is no client with given clientId
	 * 
	 * @param clientId
	 * @return
	 */
	private static Client getClientOrThrow(String clientId) {
		Client c = ClientPool.getClient(clientId);
		if (c == null) {
			throw new IllegalArgumentException(MessageFormat.format("Client with id={0} is unknown", new Object[] { clientId }));
		}

		return c;
	}

	public GreetingServiceImpl() {
		super();
	}

	@Override
	public String serverConnect(ClientLoginData loginData) throws Exception {
		AssertUtil.notNull(loginData, "loginData");

		Client c = ClientFactory.create(loginData);
		String clientId = c.getClientId();

		ClientPool.addClient(clientId, c);

		return clientId;
	}

	@Override
	public Boolean serverDisconnect(String clientId) {
		AssertUtil.notNull(clientId, "clientId");

		Client c = getClientOrThrow(clientId);
		c.serverDisconnect();

		return Boolean.TRUE;
	}

	@Override
	public Boolean waveNew(String clientId) throws Exception {
		AssertUtil.notNull(clientId, "clientId");

		Client c = getClientOrThrow(clientId);
		c.createNewWave();

		return Boolean.TRUE;
	}

	@Override
	public Boolean waveOpen(String clientId, String waveId) throws Exception {
		AssertUtil.notNull(clientId, "clientId");
		AssertUtil.notNull(waveId, "waveId");

		Client c = getClientOrThrow(clientId);
		c.openWave(waveId);

		return Boolean.TRUE;
	}

	@Override
	public Boolean waveAddParticipant(String clientId, String waveId, String participantName) throws Exception {
		AssertUtil.notNull(clientId, "clientId");
		AssertUtil.notNull(waveId, "waveId");
		AssertUtil.notNull(participantName, "participantName");

		Client c = getClientOrThrow(clientId);
		c.addParticipant(waveId, participantName);

		return Boolean.TRUE;
	}

	/**
	 * Send a mutation across the wire that appends text to the currently open
	 * document, and inserting a new line element with us as the author.
	 * 
	 * @param text
	 *          text to append and send
	 * @throws Exception
	 */
	public void sendAppendMutation(String clientId, String waveId, String text) throws Exception {
		AssertUtil.notNull(clientId, "clientId");
		AssertUtil.notNull(waveId, "waveId");
		AssertUtil.notNull(text, "text");

		Client c = getClientOrThrow(clientId);
		c.sendAppendMutation(waveId, text);
	}

}